 
/*							*/
/*	Indexed Sequential Access Method		*/
/*	Relational Database Systems, Inc.		*/
/*							*/
/*		Proprietary Data			*/
/*    This document contains proprietary information	*/
/* and trade secrets which are the property of		*/
/* Relational Database Systems, Inc. (RDSI). This	*/
/* document is submitted to recipient in confidence.	*/
/* The information contained herein may not be used,	*/
/* copied or disclosed in whole or in part except as	*/
/* permitted by written agreement signed by an officer	*/
/* of RDSI.						*/
/*							*/

/*
 * Audit trail management routines
 *
 *  Relational Database Systems, Inc.
 *  Roy Harrington	January 5, 1982
 */

#include "isdec.c"

#ifndef ISKERNEL
#define fubyte(p)	(*(p))
#define subyte(p,c)	(*(p)=(c))
#endif  /* ISKERNEL */

#ifndef NOAUDIT		/* no audit code at all, if NOAUDIT defined */

isaudit(isfd, fname, mode)
int isfd;
char *fname;
int mode;
{
	register struct buff *bp;
	long audnode;

	if (isenter(isfd, ISOUTPUT) == -1) return(-1);

	switch(mode)
	    {
	    case AUDSETNAME:
		if (ld1(dictp->d_audit) & 0x80)		/* must be stopped */
		    goto bad;
		if (stleng(fname) > PATHSIZE)
		    goto bad;
#ifndef ISKERNEL
		if (makefile(fname) && iserrno != EEXIST)
		    goto bad;
#endif  /* ISKERNEL */
		iserrno = 0;
		if ((audnode = ld4(dictp->d_audit)) == 0L)
		    {
		    audnode = allocrec(INDXREC);
		    bp = bfgetclr(audnode);
		    st4(audnode, dictp->d_audit);
		    filep->f_dicbp->bf_flags |= BFMODF;
		    }
		else bp = bfread(audnode & 0x7FFFFFFF);
		if (bp == NULL) break;
		stcopy(fname, bp->bf_un.bf_audt->an_filename);
		bp->bf_used = 5 + stleng(fname);
		bfdwrite(bp);
		break;

	    case AUDGETNAME:
		if ((audnode = ld4(dictp->d_audit)) == 0L)
		    goto bad;
		bp = bfread(audnode & 0x7FFFFFFF);
		if (bp == NULL) break;
		stcopy(bp->bf_un.bf_audt->an_filename, fname);
		bfrelease(bp);
		break;

	    case AUDSTART:
		if (ld4(dictp->d_audit) == 0L)
		    goto bad;
		dictp->d_audit[0] |= 0x80;
		filep->f_dicbp->bf_flags |= BFMODF;
		break;

	    case AUDSTOP:
		if ((ld1(dictp->d_audit) & 0x80) &&
			(filep->f_flags & FAUDOPEN))
		    {
		    VOID close(filep->f_audfd);
		    filep->f_flags &= ~FAUDOPEN;
		    }
		dictp->d_audit[0] &= ~0x80;
		filep->f_dicbp->bf_flags |= BFMODF;
		break;

	    case AUDINFO:
		*fname = ((ld1(dictp->d_audit) & 0x80) != 0);
		break;
	    }

	return(isexit());
bad:
	if (iserrno == 0) iserrno = EBADARG;
	return(isexit());
}



/*
 * open audit trail
 */

STATIC int audopen()
{
	long audnode;
	register struct buff *bp;
	register struct audt *audp;

	if (filep->f_flags & FAUDOPEN)
	    return(0);			/* audit trail already opened	*/
	if ((ld1(dictp->d_audit) & 0x80) == 0)
	    return(0);			/* no audit trail defined	*/

	audnode = ld4(dictp->d_audit);
	bp = bfread(audnode & 0x7FFFFFFF);
	if (bp == NULL) return(-1);
	audp = bp->bf_un.bf_audt;
	if ((filep->f_audfd = open(audp->an_filename, WMODE)) == -1)
	    {
	    iserrno = errno;
	    iserrio = IO_OPEN+IO_AUD;
	    }
	else filep->f_flags |= FAUDOPEN;

	bfrelease(bp);
	return(iserrno ? -1 : 0);
}


/*
 * output an audit trail record
 */

STATIC int audoutput(type, record)

char type;
char *record;

{
	struct audhead head;
	long autime;
#ifndef ISKERNEL
	long time();
#endif
	register int datsize;
	register int savebyte;

	if ( ! (ld1(dictp->d_audit) & 0x80))
	    return;				/* audit trail off	*/
	if ( ! (filep->f_flags & FAUDOPEN))
	    return;
	
	if (lseek(filep->f_audfd, 0L, 2) == -1L)/* seek to end of file	*/
	    {
	    iserrno = errno;
	    iserrio = IO_SEEK+IO_AUD;
	    return;
	    }

#ifndef ISKERNEL
	autime = time(&autime);		/* else function call		*/
#else
	autime = time;			/* global variable in kernel	*/
#endif

	st1(type, head.au_type);
	st4(autime, head.au_time);
	st2(openp->o_procid, head.au_procid);
	st2(openp->o_userid, head.au_userid);

	datsize = filep->f_datsize;
	savebyte = fubyte(record+datsize);
	subyte(record+datsize, '\n');

	if ((write(filep->f_audfd, CASTCP &head, AUDHEADSIZE) != AUDHEADSIZE) ||
	    (write(filep->f_audfd, record, datsize+1) != datsize+1))
	    {
	    iserrno = errno;
	    iserrio = IO_WRIT+IO_AUD;
	    }

	subyte(record+datsize, savebyte);
}

#endif		/* NOAUDIT */
